package com.pinecone.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pinecone.common.exception.MinerException;
import com.pinecone.common.utils.HttpClientUtils;
import com.pinecone.common.utils.TxVideoUtils;
import com.pinecone.dao.LiveRecordTaskDao;
import com.pinecone.dao.LiveRoomDao;
import com.pinecone.entity.LiveRecordTaskEntity;
import com.pinecone.entity.LiveRoomEntity;
import com.pinecone.service.TxVideoService;
import com.qcloud.Module.Vod;
import com.qcloud.QcloudApiModuleCenter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by hushangjie on 2017/9/13.
 */
@Service
public class TxVideoServiceImpl implements TxVideoService {
    protected static final Logger logger = LoggerFactory.getLogger(TxVideoServiceImpl.class);

    @Autowired
    private LiveRecordTaskDao recordTaskDao;
    @Autowired
    private LiveRoomDao liveRoomDao;
    @Value("${txvideo.apikey}")
    private String apikey;
    @Value("${txvideo.appid}")
    private Integer appid;

    //查询某个时间段直播在线人数
    @Async
    public void setOnlineMaxNumber(String streamId, Date endTime) {
        String urlNameString = "http://statcgi.video.qcloud.com/common_access?" +
                "cmd=CMD&interface=INTERFACE&Param.n.start_time=STIME&Param.n.end_time=ENDTIME&Param.s.stream_id=STREAMID" +
                "&t=TXTIME&sign=SIGN";

        //获取24小时前的在线人数统计
        Integer onlineMaxNumber = 0;
        Long startTime = (endTime.getTime() - 24 * 60 * 60 * 1000) / 1000;
        Long timeEnd = endTime.getTime() / 1000;
        Date now = new Date();
        Long txTime = (now.getTime() + 60 * 1000 * 10) / 1000;
        String sign = TxVideoUtils.md5(apikey + txTime);

        urlNameString = urlNameString.replace("CMD", appid.toString());
        urlNameString = urlNameString.replace("INTERFACE", "Get_LivePlayStatHistory");
        urlNameString = urlNameString.replace("STIME", startTime.toString());
        urlNameString = urlNameString.replace("ENDTIME", timeEnd.toString());
        urlNameString = urlNameString.replace("TXTIME", txTime.toString());
        urlNameString = urlNameString.replace("STREAMID", streamId);
        urlNameString = urlNameString.replace("SIGN", sign);
        JSONObject jsonObject = HttpClientUtils.httpGet(urlNameString);
        if (jsonObject.get("ret").toString().equals("0")) {
            //定义集合存放各个时间段在线人数，取最大值
            //未来可将全部数据取出做数据分析
            List<Integer> onList = new ArrayList<>();
            JSONObject output = jsonObject.getJSONObject("output");
            if (output.getJSONArray("stat_info") != null){
                JSONArray stat_info = output.getJSONArray("stat_info");
                if(stat_info.size()>0){
                    for(int i=0;i<stat_info.size();i++){
                        JSONObject online = stat_info.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                        onList.add(online.getInteger("online"));    // 得到 每个对象中的属性值
                    }
                }
            }
            //取出集合内最大值
            onlineMaxNumber = Collections.max(onList);
        }
        //更新直播间并发数
        String liveRoomId = streamId.substring(streamId.indexOf("_")+1,streamId.length());
        LiveRoomEntity liveRoomEntity = liveRoomDao.queryObject(liveRoomId);
        liveRoomEntity.setMaxOnlineNumber(onlineMaxNumber);
        liveRoomDao.update(liveRoomEntity);
    }

    /**
     * 获取直播流在某个时间段的流量(24小时内)
     * @param streamId
     * @param timeStart
     * @return
     */
    public Double getSumFlux(String streamId, Date timeStart) {
        String urlNameString = "http://statcgi.video.qcloud.com/common_access?" +
                "cmd=CMD&interface=INTERFACE&Param.n.start_time=STIME&Param.n.end_time=ENDTIME&Param.s.stream_id=STREAMID" +
                "&t=TXTIME&sign=SIGN";
        Long startTime = timeStart.getTime()/1000;
        Long endTime = (timeStart.getTime()+24*60*60*1000)/1000;
        Date now = new Date();
        Long txTime = (now.getTime()+60*1000*10)/1000;
        String sign = TxVideoUtils.md5(apikey+txTime);

        urlNameString=urlNameString.replace("CMD", appid.toString());
        urlNameString=urlNameString.replace("INTERFACE","Get_LivePlayStatHistory");
        urlNameString=urlNameString.replace("STIME",startTime.toString());
        urlNameString=urlNameString.replace("ENDTIME",endTime.toString());
        urlNameString=urlNameString.replace("TXTIME",txTime.toString());
        urlNameString=urlNameString.replace("STREAMID",streamId);
        urlNameString=urlNameString.replace("SIGN",sign);
        JSONObject jsonObject = HttpClientUtils.httpGet(urlNameString);
        Double sumFlux = 0.0;

        if (jsonObject.get("ret").toString().equals("0")){
            JSONObject output = jsonObject.getJSONObject("output");
            if (output.getJSONObject("sum_info") != null){
                JSONObject sumInfo = output.getJSONObject("sum_info");
                Double getSumFlux = sumInfo.getDouble("sum_flux")/1024;
                BigDecimal  b = new BigDecimal(getSumFlux);
                sumFlux = b.setScale(2,BigDecimal.ROUND_UP).doubleValue();
            }
        }else {
            throw new MinerException("查询流量统计失败",506);
        }
        //获取该直播间24小时内的流量


        return sumFlux;
    }

    /**
     *禁播服务
     * @param streamId
     * @param liveState 0表示禁用； 1表示允许推流；2表示断流
     */
    @Override
    public void switchLiveState(String streamId, Integer liveState) {
        Date now = new Date();
        Long txTime = (now.getTime()+60*1000*10)/1000;
        String sign = TxVideoUtils.md5(apikey+txTime);

        String urlNameString = "http://fcgi.video.qcloud.com/common_access?" +
                "appid=APPID&interface=INTERFACE&Param.s.channel_id=STREAMID&Param.n.status=STATUS" +
                "&t=TXTIME&sign=SIGN";
        urlNameString=urlNameString.replace("STREAMID",streamId);
        urlNameString=urlNameString.replace("SIGN",sign);
        urlNameString=urlNameString.replace("APPID",appid.toString());
        urlNameString=urlNameString.replace("INTERFACE","Live_Channel_SetStatus");
        urlNameString=urlNameString.replace("STATUS",liveState.toString());
        urlNameString=urlNameString.replace("TXTIME",txTime.toString());

        JSONObject jsonObject = HttpClientUtils.httpGet(urlNameString);
        Integer ret = jsonObject.getInteger("ret");
        if (ret != null && ret == 0){
          //禁播逻辑
        }else {
            throw new MinerException("更改直播状态失败",506);
        }


    }

    /**
     * 创建录制任务，在收到直播推流通知即开始录制
     * @param timeStart
     * @param streamId
     * @throws UnsupportedEncodingException
     */
    @Override
    public void createRecordTask(Date timeStart, String streamId) throws UnsupportedEncodingException {
        String urlNameString = "http://fcgi.video.qcloud.com/common_access?" +
                "appid=APPID&interface=Live_Tape_Start" +
                "&Param.s.channel_id=STREAMID" +
                "&Param.s.start_time=TIMESTART" +
                "&Param.s.end_time=TIMEEND" +
                "&t=TXTIME&sign=SIGN&Param.n.task_sub_type=1" +
                "&Param.s.file_format=hls&Param.s.record_type=video";
        //判断该频道是否已经正在录制
        LiveRecordTaskEntity recordTaskEntityOn = recordTaskDao.quertByStreamIdNotOver(streamId);

        if (recordTaskEntityOn != null){
            //正在录制中
            return;
        }

        Date now = new Date();
        Long txTime = (now.getTime()+60*1000*10)/1000;
        String sign = TxVideoUtils.md5(apikey+txTime);

        String time_start = URLEncoder.encode(timeStart.toString(),"utf-8");
        //设置录制结束时间，一般通过主动停止录制
        Calendar timeEnd = Calendar.getInstance();
        timeEnd.setTime(timeStart);
        timeEnd.add(Calendar.DATE,1);
        String time_end = URLEncoder.encode(timeEnd.toString(),"utf-8");

        urlNameString=urlNameString.replace("TXTIME",txTime.toString());
        urlNameString=urlNameString.replace("SIGN",sign);
        urlNameString=urlNameString.replace("TIMEEND",time_end);
        urlNameString=urlNameString.replace("TIMESTART",time_start);
        urlNameString=urlNameString.replace("STREAMID",streamId);
        urlNameString=urlNameString.replace("APPID",appid.toString());

        JSONObject jsonObject = HttpClientUtils.httpGet(urlNameString);
        System.out.println("create record"+jsonObject);
        Integer ret = jsonObject.getInteger("ret");
        if (ret != null && ret == 0){
            JSONObject output = jsonObject.getJSONObject("output");
            //添加录制记录
            LiveRecordTaskEntity recordTaskEntity = new LiveRecordTaskEntity();
            recordTaskEntity.setStreamId(streamId);
            recordTaskEntity.setOver(false);
            recordTaskEntity.setRecordTime(new Date());
            recordTaskEntity.setTaskId(output.getInteger("task_id"));
            recordTaskDao.save(recordTaskEntity);
            logger.info("开启录制",streamId);
        }else {
            logger.error("开启录制失败",jsonObject.get("message"));
            throw new MinerException("录制失败",506);
        }

    }

    /**
     * 结束录制任务，当收到断流消息开始结束录制
     * @param streamId
     */
    @Override
    public void stopRecordTask(String streamId) {
        String urlNameString = "http://fcgi.video.qcloud.com/common_access?" +
                "appid=APPID&interface=Live_Tape_Stop" +
                "&Param.s.channel_id=STREAMID" +
                "&Param.n.task_id=TASKID" +
                "&t=TXTIME&sign=SIGN";
        Date now = new Date();
        Long txTime = (now.getTime()+60*1000*10)/1000;
        String sign = TxVideoUtils.md5(apikey+txTime);
        LiveRecordTaskEntity recordTaskEntity = recordTaskDao.quertByStreamIdNotOver(streamId);

        urlNameString=urlNameString.replace("TXTIME",txTime.toString());
        urlNameString=urlNameString.replace("SIGN",sign);
        urlNameString=urlNameString.replace("APPID",appid.toString());
        urlNameString=urlNameString.replace("TASKID",recordTaskEntity.getTaskId().toString());
        urlNameString=urlNameString.replace("STREAMID",streamId);
        JSONObject jsonObject = HttpClientUtils.httpGet(urlNameString);
        Integer ret = 0;
        if (jsonObject != null){
            ret = jsonObject.getInteger("ret");
        }
        if (ret != null){
            //结束录制,更新记录表
            recordTaskEntity.setOver(true);
            recordTaskEntity.setOverTime(new Date());
            recordTaskDao.update(recordTaskEntity);

        }else {
            logger.error("结束录制失败",jsonObject.get("message"));
            throw new MinerException("结束录制失败",506);
        }

    }

    /**
     * 是否开启截图服务，每10s一张，费用。。。
     * @param streamId
     */
    @Override
    public void createLiveShot(String streamId) {

    }

    @Override
    public void deleteVideoById(String fileId) {
        TreeMap<String, Object> config = new TreeMap<String, Object>();
        config.put("SecretId", "AKIDdJrEONQLEyWs22NSXUFoBMK6jCVdbP0P");
        config.put("SecretKey", "LURJ0LchbIqCPRMUYSAj6GE2dAnrnX5R");
        config.put("RequestMethod", "GET");
        config.put("DefaultRegion", "gz");
        QcloudApiModuleCenter module = new QcloudApiModuleCenter(new Vod(),config);
        TreeMap<String, Object> params = new TreeMap<String, Object>();
        params.put("fileId",fileId);
        params.put("priority",0);
        String result = null;
        try {
		/* call 方法正式向指定的接口名发送请求，并把请求参数params传入，返回即是接口的请求结果。 */
            result = module.call("DeleteVodFile", params);
            JSONObject json_result = JSONObject.parseObject(result);
            if(json_result.getInteger("code") == 0){
                //删除成功
            }else {
                logger.error("腾讯云点播文件删除失败"+"文件id=="+fileId);
                logger.error("错误原因:"+json_result.get("message"));
                throw new MinerException("视频文件删除失败");
            }
        } catch (Exception e) {
            logger.error("腾讯云点播文件删除出错:"+e.getMessage());
            throw new MinerException("视频文件删除失败");
        }
    }
}
